package cn.itigger.generate.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.JCheckBox;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.VelocityContext;

import cn.itigger.generate.util.CodeResourceUtil;
import cn.itigger.generate.util.ColumnData;
import cn.itigger.generate.util.CommUtil;
import cn.itigger.generate.util.CommonPageParser;

import com.alibaba.fastjson.JSON;

public class CodeGenerateFactory {
	private static final Log log = LogFactory.getLog(CodeGenerateFactory.class);
	private static String url = CodeResourceUtil.URL;
	private static String username = CodeResourceUtil.USERNAME;
	private static String passWord = CodeResourceUtil.PASSWORD;

	private static String buss_package = CodeResourceUtil.bussiPackage;
	private static String projectPath = getProjectPath();

	private static Map<String, JCheckBox> cfg;

	public static void codeGenerate(Map<String, String> data,
			Map<String, JCheckBox> c) {
		cfg = c;
		codeGenerate(data);
	}

	public static boolean isCreate(String key) {
		JCheckBox value = cfg.get(key);
		return value != null && value.isSelected();
	}
	
	public static Map<String, Object> cloneMap(Map<String, Object> source){
		Map<String, Object> result = new HashMap<String, Object>();
		for(Entry<String, Object> entry : source.entrySet()){
			result.put(entry.getKey(), entry.getValue());
		}
		return result;
	}
	
	

	public static void codeGenerate(Map<String, String> data) {
		CreateBean createBean = new CreateBean();

		String dataBase = url.substring(0, url.indexOf("?"));

		dataBase = dataBase.substring(dataBase.lastIndexOf("/") + 1);

		String projectName = data.get("projectName");

		String table = data.get("table");

		String workSpace = data.get("workSpace");

		String basePackage = data.get("basePackage");

		String prefix = data.get("prefix");

		String webPath = data.get("webPath");

		createBean.setMysqlInfo(url, username, passWord);

		String className = createBean.getTablesNameToClassName(table);

		String lowerName = className.substring(0, 1).toLowerCase()
				+ className.substring(1, className.length());

		VelocityContext context = new VelocityContext();
		context.put("prefix", prefix);
		context.put("className", className);
		context.put("lowerName", lowerName);
		context.put("tableName", table);
		context.put("bussPackage", buss_package);
		String aliasName = table.substring(0, 1); // 表别名
		try {
			context.put("basePackage", basePackage);
			context.put("tableComment",
					createBean.getTableComment(dataBase, table));

			Map<String, String> beanFields = createBean.getBeanFeilds(dataBase,
					table, aliasName, basePackage);
			context.put("feilds", beanFields.get("feilds"));
			context.put("imports", beanFields.get("imports"));
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			Map sqlMap = createBean
					.getAutoCreateSql(dataBase, table, aliasName);
			context.put("aliasName", aliasName);

			List<ColumnData> columnDatas = createBean.getColumnDatas(dataBase,
					table, aliasName);

			context.put("columnDatas", columnDatas);

			context.put("SQL", sqlMap);

			List<Map<String, Object>> showFieldList = new ArrayList<Map<String, Object>>();

			List<Map<String, Object>> editFieldList = new ArrayList<Map<String, Object>>();

			for (int i = 0; i < columnDatas.size(); i++) {
				Map<String, Object> field = new HashMap<String, Object>();

				String comment = columnDatas.get(i).getColumnComment();

				boolean hasComment = comment.contains("(")&& comment.contains(")")&& comment.contains(":");

				field.put(
						"desc",
						"'"
								+ (hasComment ? comment.substring(0,
										comment.lastIndexOf("(")) : comment)
								+ "'");
				field.put("name", "'"
						+ columnDatas.get(i).getFormatColumnName() + "'");

				Map<String, Object> editField = cloneMap(field);
				editField.put("class", "'width-300'");

				if (columnDatas.get(i).getColumnType().equals("datetime")) {
					editField.put("type", "'date'");
					editField.remove("class");
					editField.put("leftCss", "{'width':'262px'}");
				}else if (columnDatas.get(i).getColumnType().equals("int")||columnDatas.get(i).getColumnType().equals("double")) {
					editField.put("type", "'int'");
				}else if (columnDatas.get(i).getColumnType().equals("text")) {
					editField.put("type", "'textarea'");
				}
				
				if(columnDatas.get(i).getNullable().equals("N")){
					editField.put("notNull", true);
				}

				if (hasComment) {

					String desc = comment.substring(
							comment.lastIndexOf("(") + 1,
							comment.lastIndexOf(")"));

					String[] list = desc.split(",");

					List<Map<String, Object>> selectList = new ArrayList<Map<String, Object>>();

					String formatContent = "";
					

					for (int j = 0; j < list.length; j++) {
						String[] temp = list[j].split(":");
						formatContent += (j > 0 ? "else " : "") + "if(value=='"
								+ temp[0] + "'){" + "desc = '" + temp[1] + "';"
								+ "}";

						Map<String, Object> map = new HashMap<String, Object>();
						map.put("value", "'" + temp[0] + "'");
						map.put("desc", "'" + temp[1] + "'");

						selectList.add(map);
					}

					String format = "function(tr,value){" + "var desc = '';"
							+ formatContent + "tr.append('<td>'+desc+'</td>');"
							+ "}";

					field.put("format", format);

					editField.put("type", "'select'");
					editField.put("list", selectList);

				}

				editFieldList.add(editField);
				showFieldList.add(field);
			}

			Map<String, Object> opt = new HashMap<String, Object>();
			opt.put("desc", "'操作'");
			opt.put("name", "'opt'");
			opt.put("format", "function(tr) {"
					+ "tr.append('<td class=\"width-300\"></td>');" + "}");
			showFieldList.add(opt);

			showFieldList.remove(0);
			context.put("showFieldList", JSON.toJSONString(showFieldList)
					.replace("\"", ""));

			
			List<Map<String, Object>> searchFiledList = new ArrayList<Map<String, Object>>();
			for (Map<String, Object> map : editFieldList) {
				Map<String, Object> temp = cloneMap(map);
				temp.remove("notNull");
				if(temp.get("type")!=null&&temp.get("type").toString().equals("textarea")){
					temp.remove("type");
				}
				
				if(temp.get("list")!=null){
					List<Map<String, Object>> tempList =  (List<Map<String, Object>>) JSON.parse(JSON.toJSONString(temp.get("list")));
					Map<String, Object> m = new HashMap<String, Object>();
					m.put("desc", "'全部'");
					tempList.add(0,m);
					temp.put("list", tempList);
				}
				
				searchFiledList.add(temp);
			}
			
			
			context.put("searchFiledList", JSON.toJSONString(searchFiledList)
					.replace("\"", ""));

			editFieldList.remove(0);

			for (Map<String, Object> map : editFieldList) {
				if (map.get("class") == null) {
					map.put("leftCss", "{'width':'462px'}");
				} else {
					map.put("class", "'width-500'");
				}

			}

			context.put("editFiledList", JSON.toJSONString(editFieldList)
					.replace("\"", ""));

		} catch (Exception e) {
			e.printStackTrace();
			return;
		}

		String basePackagePath = basePackage.replace(".", "\\");

		String codePath = workSpace + "\\" + projectName + "\\src\\main\\";

		String controllerPath = codePath + "java\\" + basePackagePath
				+ "\\controller\\";
		String servicePath = codePath + "java\\" + basePackagePath
				+ "\\service\\";
		String voPath = codePath + "java\\" + basePackagePath + "\\domain\\";
		String mapperPath = codePath + "java\\" + basePackagePath
				+ "\\mapper\\";
		String mapperXmlPath = codePath + "resources\\mapper\\";
		String pagePath = codePath + webPath;

		if (isCreate("entity")) {
			CommonPageParser.WriterPage(context, "EntityTemplate.ftl", voPath,
					className + "VO.java");
		}
		if (isCreate("mapper")) {
			CommonPageParser.WriterPage(context, "DaoTemplate.ftl", mapperPath,
					className + "Mapper.java");
		}
		if (isCreate("mapper_xml")) {
			CommonPageParser.WriterPage(context, "MapperTemplate.xml",
					mapperXmlPath, CommUtil.first2low(className)
							+ "-mapper.xml");
		}

		if (isCreate("service")) {
			CommonPageParser.WriterPage(context, "ServiceTemplate.ftl",
					servicePath, className + "Service.java");
		}

		if (isCreate("controller")) {
			CommonPageParser.WriterPage(context, "ControllerTemplate.ftl",
					controllerPath, className + "Controller.java");
		}

		if (isCreate("page")) {
			CommonPageParser.WriterPage(context, "htmlListTemplate.ftl",
					pagePath, table + ".html");
			CommonPageParser.WriterPage(context, "htmlEditTemplate.ftl",
					pagePath, "edit_" + table + ".html");

			CommonPageParser.WriterPage(context, "jsListTemplate.ftl", pagePath
					+ "js/", table + ".js");
			CommonPageParser.WriterPage(context, "jsEditTemplate.ftl", pagePath
					+ "js/", "edit_" + table + ".js");
		}

		log.info("----------------------------\u4EE3\u7801\u751F\u6210\u5B8C\u6BD5---------------------------");
	}

	public static String getProjectPath() {
		String path = System.getProperty("user.dir").replace("\\", "/");
		return path;
	}
}